#include "myflagwidget.h"
#include <math.h>
#include <qdebug.h>

static float points[45][45][3];
static int wiggel_count=0;
static GLfloat hold;
MyFlagWidget::MyFlagWidget():
    QGLWidget()
{
    mRotate_z=mRotate_y=mRotate_x=0;
    connect(&mTimer,SIGNAL(timeout()),this,SLOT(updatePoints()));
    mAngle=0;
    mTimer.start(30);
}

MyFlagWidget::~MyFlagWidget()
{

}
void MyFlagWidget::updatePoints()
{
    /*
     * 映射点,[-4.5,4.5]
    */
    for(int x=0;x<45;x++)
    {
        for(int y=0;y<45;y++)
        {
            points[x][y][0]=float((x/5.0)-4.5);
            points[x][y][1]=float((y/5.0)-4.5);
            points[x][y][2]=float(sin(((x/5.0)*40.0+mAngle)/360.0*M_PI*2));
        }
    }
    mAngle+=5;
    updateGL();
}

void MyFlagWidget::initializeGL()
{
    glShadeModel(GL_SMOOTH);

    glClearColor(0,0,0,1);
    glClearDepth(1.0);

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);

    glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);

    glPolygonMode(GL_FRONT,GL_FILL);
    glPolygonMode(GL_BACK,GL_FILL);


    LoadGLTextures();
    /*
     * 需要glEnable纹理
    */
    glEnable(GL_TEXTURE_2D);

}

void MyFlagWidget::resizeGL(int w, int h)
{
    glViewport(0,0,w,h);

    glMatrixMode(GL_PROJECTION);
    glFrustum(-2,2,-(float)h/w*2,(float)h/w*2,1,20);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void MyFlagWidget::paintGL()
{
    int x,y;
    float float_x,float_y,float_xb,float_yb;
    /*
     * 1、清除颜色，深度缓存，复位矩阵
     * 2、 改变视图坐标
     * 3、画图(每个顶点先选纹理坐标，再画顶点坐标glTexCoord2f->glVertex3f）
     */
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    glTranslatef(0,0,-10);

    glRotatef(mRotate_z,0,0,1);
    glRotatef(mRotate_y,0,1,0);
    glRotatef(mRotate_x,1,0,0);

    glBindTexture(GL_TEXTURE_2D,mTexture[0]);

    glBegin(GL_QUADS);
    for(x=0;x<44;x++)
    {
        for(y=0;y<44;y++)
        {
            float_x=float(x)/44.0;
            float_y=float(y)/44.0;
            float_xb=float(x+1)/44.0;
            float_yb=float(y+1)/44.0;
            glTexCoord2f(float_x,float_y);
            glVertex3f(points[x][y][0],points[x][y][1],points[x][y][2]);

            glTexCoord2f(float_x,float_yb);
            glVertex3f(points[x][y+1][0],points[x][y+1][1],points[x][y+1][2]);

            glTexCoord2f(float_xb,float_yb);
            glVertex3f(points[x+1][y+1][0],points[x+1][y+1][1],points[x+1][y+1][2]);

            glTexCoord2f(float_xb,float_y);
            glVertex3f(points[x+1][y][0],points[x+1][y][1],points[x+1][y][2]);

        }
    }
    glEnd();
}
int MyFlagWidget::LoadGLTextures()
{
    QImage image("G:\\Project\\OpenGL\\lena.jpg");
    if(image.isNull())
    {
        qDebug()<<"Image Is Null";
        return 1;
    }
    else
        qDebug()<<"w:"<<image.width();
    QImage Tex=QGLWidget::convertToGLFormat(image);

    glGenTextures(3,mTexture);

    glBindTexture(GL_TEXTURE_2D,mTexture[0]);
    glTexImage2D(GL_TEXTURE_2D,0,3,image.width(),image.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,Tex.bits());
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);

    glBindTexture(GL_TEXTURE_2D,mTexture[1]);
    glTexImage2D(GL_TEXTURE_2D,0,3,image.width(),image.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,Tex.bits());
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

    glBindTexture(GL_TEXTURE_2D,mTexture[2]);
    glTexImage2D(GL_TEXTURE_2D,0,3,image.width(),image.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,Tex.bits());
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NICEST);
}
void MyFlagWidget::keyPressEvent(QKeyEvent* e)
{
    switch(e->key())
    {
    case Qt::Key_Left:
        mRotate_z-=10;
        break;
    case Qt::Key_Right:
        mRotate_z+=10;
        break;
    case Qt::Key_Up:
        mRotate_x-=10;
        break;
    case Qt::Key_Down:
        mRotate_x+=10;
        break;
    case Qt::Key_Plus:
        mMove_z+=1;
        break;
    case Qt::Key_Minus:
        mMove_z-=1;
        break;
    case Qt::Key_L:
    {
        GLboolean light;
        glGetBooleanv(GL_LIGHTING,&light);
        light=!light;
        if(light)
            glEnable(GL_LIGHTING);
        else
            glDisable(GL_LIGHTING);
    }
    case Qt::Key_B:
    {
        GLboolean blend;
        glGetBooleanv(GL_BLEND,&blend);
        blend=!blend;
        if(blend)
        {
            glEnable(GL_BLEND);
            glDisable(GL_DEPTH_TEST);
        }
        else
        {
            glDisable(GL_BLEND);
            glEnable(GL_DEPTH_TEST);
        }
    }
    }
    updateGL();
}
